#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
 
typedef struct{
	  ngx_http_complex_value_t   complex; 
 
      ngx_http_regex_t          *regex;
} bingo_read_conf2_t;

static ngx_int_t bingo_init(ngx_conf_t *cf);

static void *bingo_create_loc_conf(ngx_conf_t *cf);
/*
static char *ngx_http_hello_string(ngx_conf_t *cf,ngx_command_t *cmd,void *conf);

static char *ngx_http_hello_counter(ngx_conf_t *cf,ngx_command_t *cmd, void *conf);
*/

static char *bingo_set_complex_slot(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);


static ngx_command_t bingo_commands[] = {
	{ 
    	ngx_string("bingo_redirect"),
    	NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
    	bingo_set_complex_slot,
    	NGX_HTTP_LOC_CONF_OFFSET,
    	0,
    	NULL
    },
    ngx_null_command
};


static ngx_http_module_t bingo_module_ctx = {
	NULL, /*preconfiguration */
	bingo_init, /*postconfiguration */
	NULL,  /* create main configuration */
	NULL, /*init main configuration */

	NULL,   /*create server configuration */
	NULL,   /*merge server configuration */

	bingo_create_loc_conf,  /*create location configuration */
	NULL    /* merge location configuration */
};

ngx_module_t bingo_read_conf2_module = {
	NGX_MODULE_V1,
	&bingo_module_ctx,    /*module context */
	bingo_commands,       /* module directives */
	NGX_HTTP_MODULE,               /* module type */
	NULL,                          /* init master */
	NULL,							/*init module */
	NULL,							/*int process */
	NULL,							/*init thread */
	NULL,							/* exit thread */
	NULL,							/* exit process */
	NULL,							/* exit master */
	NGX_MODULE_V1_PADDING
};


static ngx_int_t bingo_rewrite_regex(ngx_conf_t *cf,bingo_read_conf2_t *blcf,ngx_str_t *pattern){

	u_char               errstr[NGX_MAX_CONF_ERRSTR];
    ngx_regex_compile_t  rc;

    ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

    rc.pattern = *pattern;
    rc.err.len = NGX_MAX_CONF_ERRSTR;
    rc.err.data = errstr;

    rc.options = NGX_REGEX_CASELESS;
 
    blcf->regex = ngx_http_regex_compile(cf, &rc);
	ngx_log_error(NGX_LOG_EMERG, cf->log,0,"ngx_http_hello_handler is called!");
 

    if (blcf->regex == NULL  ) {
        return NGX_ERROR;
    }


    return NGX_OK; 

}


char *bingo_set_complex_slot(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf){
	bingo_read_conf2_t *blcf = conf;

    ngx_str_t                         *value;

   
    ngx_http_compile_complex_value_t   ccv;
    
    value = cf->args->elts;

    ngx_memzero(&blcf->complex, sizeof(ngx_http_complex_value_t));

    bingo_rewrite_regex(cf,blcf,&value[1]);
    
     
    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

    ccv.cf = cf;
    ccv.value = &value[2];
    ccv.complex_value = &blcf->complex;
   
      if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
        return NGX_CONF_ERROR;
    }



    return NGX_CONF_OK;
}


static ngx_int_t bingo_handler(ngx_http_request_t *r){
 	ngx_str_t tokens;
 	bingo_read_conf2_t* bingo_conf;
 

	ngx_log_error(NGX_LOG_EMERG, r->connection->log,0,"ngx_http_hello_handler is called!");



	bingo_conf = ngx_http_get_module_loc_conf(r,bingo_read_conf2_module);

    if(!bingo_conf->regex){
    	return NGX_DECLINED;
    }


    if (ngx_http_regex_exec(r, bingo_conf->regex, &r->uri) != NGX_OK) {
        return NGX_DECLINED;
    }

	if (ngx_http_complex_value(r, &bingo_conf->complex, &tokens) != NGX_OK) {
        return NGX_ERROR;
    }

        		ngx_log_error(NGX_LOG_EMERG,r->connection->log,0,"tokens====== %V",&tokens);

     

  return 403;
}


static void *bingo_create_loc_conf(ngx_conf_t *cf){
	bingo_read_conf2_t *local_conf = NULL;
	local_conf = ngx_pcalloc(cf->pool, sizeof(bingo_read_conf2_t));
	if (local_conf == NULL)
	{
		return NULL;
	}

    return local_conf;
}
 


static ngx_int_t bingo_init(ngx_conf_t *cf){
	ngx_http_handler_pt *h;
	ngx_http_core_main_conf_t *cmcf;

	cmcf = ngx_http_conf_get_module_main_conf(cf,ngx_http_core_module);

	h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
	if(h == NULL ){
		return NGX_ERROR;
	}

	*h = bingo_handler;
	return NGX_OK;
}